import GameConfig from './GameConfig'
import { Square } from './Square'
import { SquareGroup } from './SquareGroup'
import { createTeris } from './Teris'
import { TerisRule } from './TerisRule'
import { GameStatus, GameViewer, MoveDirection } from './types'

export class Game {
  private _gameStatus: GameStatus = GameStatus.init

  private _curTeris?: SquareGroup
  private _nextTeris: SquareGroup = createTeris({ x: 0, y: 0 })
  private _timer?: ReturnType<typeof setInterval>
  private _duration = 1000
  private _exists: Square[] = []
  private _score: number = 0

  constructor(private _viewer: GameViewer) {
    this.resetCenterPoint(GameConfig.nextSize.width, this._nextTeris)
    this._viewer.showNext(this._nextTeris)
  }

  start() {
    //游戏状态的改变
    if (this._gameStatus === GameStatus.playing) {
      return
    }

    if (this._gameStatus === GameStatus.over) {
      this._exists = []
      this._nextTeris = createTeris({ x: 0, y: 0 })
      this._viewer.showNext(this._nextTeris)
      this.resetCenterPoint(GameConfig.nextSize.width, this._nextTeris)
      this._curTeris = undefined
      this._score = 0
      this._exists.forEach(sq => {
        if (sq.viewer) {
          sq.viewer.remove()
        }
      })
    }

    this._gameStatus = GameStatus.playing
    if (!this._curTeris) {
      //给当前玩家操作的方块赋值
      this.switchTeris()
    }
    this.autoDrop()
  }

  pause() {
    if (this._gameStatus === GameStatus.playing) {
      this._gameStatus = GameStatus.pause
      clearInterval(this._timer)
      this._timer = undefined
    }
  }

  control_left() {
    if (this._curTeris && GameStatus.playing === this._gameStatus) {
      TerisRule.move(this._curTeris, MoveDirection.left, this._exists)
    }
  }

  control_right() {
    if (this._curTeris && GameStatus.playing === this._gameStatus) {
      TerisRule.move(this._curTeris, MoveDirection.right, this._exists)
    }
  }

  control_down() {
    if (this._curTeris && GameStatus.playing === this._gameStatus) {
      TerisRule.MoveDirectly(this._curTeris, MoveDirection.down, this._exists)
      this.hitBottom()
    }
  }

  control_rotate() {
    if (this._curTeris && GameStatus.playing === this._gameStatus) {
      TerisRule.rotate(this._curTeris, this._exists)
    }
  }

  private autoDrop() {
    if (this._timer || this._gameStatus !== GameStatus.playing) {
      return
    }
    this._timer = setInterval(() => {
      if (this._curTeris) {
        if (!TerisRule.move(this._curTeris, MoveDirection.down, this._exists)) {
          this.hitBottom()
        }
      }
    }, this._duration)
  }
  /**
   * 切换方块
   */
  private switchTeris() {
    this._curTeris = this._nextTeris
    this.resetCenterPoint(GameConfig.panelSize.width, this._curTeris)
    const res = TerisRule.canIMove(this._curTeris.shape, this._curTeris.centerPoint, this._exists)
    if (!res) {
      this._gameStatus = GameStatus.over
      clearInterval(this._timer)
      this._timer = undefined
      return
    }
    this._nextTeris = createTeris({ x: 0, y: 0 })
    this.resetCenterPoint(GameConfig.nextSize.width, this._nextTeris)
    this._viewer.switch(this._curTeris)
    this._viewer.showNext(this._nextTeris)
  }

  private resetCenterPoint(width: number, teris: SquareGroup) {
    const x = Math.ceil(width / 2) - 1
    const y = 0
    teris.centerPoint = { x, y }
    while (teris.squares.some(it => it.point.y < 0)) {
      teris.centerPoint = { x: teris.centerPoint.x, y: teris.centerPoint.y + 1 }
    }
  }
  private hitBottom() {
    this._exists.push(...this._curTeris!.squares)
    const num = TerisRule.deleteSquares(this._exists)
    this.addScore(num)
    this.switchTeris()
  }
  private addScore(lineNum: number) {
    if (lineNum) {
      this._score += lineNum * 10
    }
  }
}
